// core/Crc32.cpp

#include "Crc32.h"

// Define
#define CRC32_POLYNOMIAL		(0x04c11db7)

// Static
bool		CORE::s_bCrc32Initialized = false;
uint32_t	CORE::s_uiCrcTable[CRC32_TABLE_SIZE];

using namespace CORE;

uint32_t Crc32_Reflect(uint32_t uIReflect, char cChar)
{
	uint32_t uIValue = 0;

	// Swap bit 0 for bit 7 bit 1 For bit 6, etc...
	for (int iPos = 1; iPos < (cChar + 1); iPos++)
	{
		if (uIReflect & 1) uIValue |= 1 << (cChar - iPos);
		uIReflect >>= 1;
	}

	return uIValue;
}

void CORE::Crc32_Init()
{
	int i, j;
	uint32_t crc;

	for (i=0; i < 256; i++)
	{
		crc = Crc32_Reflect(i, 8) << 24;

		for (j = 0; j < 8; j++)
		{
			crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0);
		}
		s_uiCrcTable[i] = Crc32_Reflect(crc, 32);
	}

	s_bCrc32Initialized = true;
}

uint32_t CORE::Crc32_Calculate(const CORE::String &aString)
{
	return Crc32_Calculate( reinterpret_cast<const byte *>( aString.GetBufferPtr() ), aString.GetLength() );
}